bitkeeper revision 1.104 (3e5cf351zM_u_gdQ7xC6wyGYbvtLAA)
authorkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Wed, 26 Feb 2003 17:03:13 +0000 (17:03 +0000)
committerkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Wed, 26 Feb 2003 17:03:13 +0000 (17:03 +0000)
e1000_main.c, e1000.h, Makefile:
  Add some locking to Intel's shoddy e1000 driver.

xen/drivers/net/Makefile
xen/drivers/net/e1000/e1000.h
xen/drivers/net/e1000/e1000_main.c

index 34954de493809e64fefa7bfc471ab91d082412dd..22277b13b21182dcf27380bcfa559ac48a7b3eee 100644 (file)
@@ -8,6 +8,7 @@ default: $(OBJS)
 
 clean:
        $(MAKE) -C ne clean
+       $(MAKE) -C e1000 clean
        rm -f *.o *~ core
 
 .PHONY: default clean
index d94e390ba3ab2fb6acca0f1b8525f1d130a2042b..01ee6b98f3bf4ffaa9ebb70d84b4922bc85f691a 100644 (file)
@@ -200,9 +200,10 @@ struct e1000_adapter {
        struct e1000_phy_info phy_info;
        struct e1000_phy_stats phy_stats;
 
-
-
        uint32_t pci_state[16];
        char ifname[IFNAMSIZ];
+
+       /* All new definitions should go below this point! */
+       spinlock_t tx_lock;
 };
 #endif /* _E1000_H_ */
index 8afbe394c2f49e3cda0aaeda345b922ead1724e1..dd0de338f0d193b02644bbb4c1bc61071e99a909 100644 (file)
@@ -362,6 +362,7 @@ e1000_probe(struct pci_dev *pdev,
        adapter->netdev = netdev;
        adapter->pdev = pdev;
        adapter->hw.back = adapter;
+       spin_lock_init(&adapter->tx_lock);
 
        mmio_start = pci_resource_start(pdev, BAR_0);
        mmio_len = pci_resource_len(pdev, BAR_0);
@@ -1439,6 +1440,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                count++;
 
        if(E1000_DESC_UNUSED(&adapter->tx_ring) < count) {
+               printk("%s: BUG! Ring full with queue awake!\n", netdev->name);
                netif_stop_queue(netdev);
                return 1;
        }
@@ -1448,15 +1450,22 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
        if(adapter->vlgrp && vlan_tx_tag_present(skb)) {
                tx_flags |= E1000_TX_FLAGS_VLAN;
-               tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
+               tx_flags |= (vlan_tx_tag_get(skb)<<E1000_TX_FLAGS_VLAN_SHIFT);
        }
 
+       spin_lock_irq(&adapter->tx_lock);
+
        count = e1000_tx_map(adapter, skb);
 
        e1000_tx_queue(adapter, count, tx_flags);
 
        netdev->trans_start = jiffies;
 
+       if(E1000_DESC_UNUSED(&adapter->tx_ring) < (MAX_SKB_FRAGS + 1))
+               netif_stop_queue(netdev);
+
+       spin_unlock_irq(&adapter->tx_lock);
+
        return 0;
 }
 
@@ -1759,6 +1768,9 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
        struct pci_dev *pdev = adapter->pdev;
        struct e1000_tx_desc *tx_desc;
        int i;
+       unsigned long flags;
+
+       spin_lock_irqsave(&adapter->tx_lock, flags);
 
        i = tx_ring->next_to_clean;
        tx_desc = E1000_TX_DESC(*tx_ring, i);
@@ -1795,6 +1807,8 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
 
                netif_wake_queue(netdev);
        }
+
+       spin_unlock_irqrestore(&adapter->tx_lock, flags);
 }
 
 /**